package com.lanou3g.ptp.achievement.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.achievement.mapper.CommentMapper;
import com.lanou3g.ptp.achievement.mapper.DiaryMapper;
import com.lanou3g.ptp.achievement.mapper.LikeMapper;
import com.lanou3g.ptp.achievement.service.DiaryService;
import com.lanou3g.ptp.entity.*;
import com.lanou3g.ptp.exception.PtpException;
import com.lanou3g.ptp.message.service.MessageService;
import com.lanou3g.ptp.signInDate.service.SignInDateService;
import com.lanou3g.ptp.student.service.StudentService;
import com.lanou3g.ptp.task.service.TaskService;
import com.lanou3g.ptp.teachlink.service.TeachlinkService;
import com.lanou3g.ptp.utils.DateUtils;
import com.lanou3g.ptp.utils.PtpResult;
import com.lanou3g.ptp.utils.PtpResultUtils;
import com.lanou3g.ptp.vo.*;
import com.lanou3g.ptp.wx.service.WxService;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.*;

@Service(timeout = 10000)
public class DiaryServiceImpl implements DiaryService {

    @Autowired
    private DiaryMapper diaryMapper;
    @Autowired
    private LikeMapper likeMapper;
    @Autowired
    private CommentMapper commentMapper;

    @Reference(lazy = true)
    private StudentService studentService;
    @Reference(lazy = true)
    private TaskService taskService;
    @Reference(lazy = true)
    private TeachlinkService teachlinkService;
    @Reference(lazy = true)
    private SignInDateService signInDateService;
    @Reference(lazy = true)
    private WxService wxService;
    @Reference(lazy = true)
    private MessageService messageService;

    //字符串处理成数组
    private List<Diary> forThis(List<Diary> diaries) {
        for (Diary diary : diaries) {
            String img = diary.getImg();
            //分割字符串
            String[] imgs;
            String meter = ",";
            imgs = img.split(meter);
            diary.setImgs(imgs);
            diary.setImg(null);
        }
        return diaries;
    }


    @Override
    public PageInfo<Diary> findAllDiary(Integer page, Integer size) {

        PageHelper.startPage(page, size);
        List<Diary> all = diaryMapper.findAll();
        List<Diary> diaries = forThis(all);
        return new PageInfo<>(diaries);

    }

    @Override
    public List<Diary> findAll1Diary() {
        List<Diary> all = diaryMapper.findAll1();
        return forThis(all);
    }

    @Override
    public PageInfo<Diary> findByKeyword(Integer page, Integer size, String keyword) {
        PageHelper.startPage(page, size);
        List<Diary> byKeyword = diaryMapper.findByKeyword("%" + keyword + "%");
        List<Diary> diaries = forThis(byKeyword);
        return new PageInfo<>(diaries);

    }

    @Override
    public Diary findDiaryById(Long id) {
        return diaryMapper.findDiaryById(id);
    }

    @Override
    public boolean insertDiary(Diary diary) {

        Date now = new Date();
        diary.setCreateTime(now);
        diary.setUpdateTime(now);
        diary.setStatus(0);

        Date startDate = DateUtils.getTodayDateIgnoreTime();
        Date endDate = DateUtils.getTomorrowDateIgnoreTime();

        boolean ifTodayInSignInDates = signInDateService.ifTodayInSignInDates(diary.getTaskId());
        if (ifTodayInSignInDates) {
            Diary diary2 = diaryMapper.findTodayDiaryByStudentId(diary.getStudentId(),
                    diary.getTaskId(), startDate, endDate);
            if (diary2 == null) {
                int i = diaryMapper.insert(diary);
                return i > 0;
            }
        }
        return false;
    }

    @Override
    public void updateDiary(Long id, Diary diary) {

        diary.setUpdateTime(new Date());
        diaryMapper.updateDiary(id, diary);

    }

    @Override
    public void deleteDiaryId(Long id) {

        diaryMapper.deleteDiaryId(id);
    }

    @Override
    public void deleteDiaryIds(Long[] ids) {

        diaryMapper.deleteDiaryIds(ids);
    }

    @Override
    public List<Diary> MyFindAll(Long id) {
        List<Diary> diaryList = diaryMapper.myFindAll(id);
        return forThis(diaryList);
    }

    @Override
    public List<Diary> findDiarySituation(Date date, Long taskId) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date time1 = cal.getTime();
        cal.get(Calendar.DAY_OF_YEAR);
        cal.add(Calendar.DATE, 1);
        Date time2 = cal.getTime();
        List<Diary> diarySituation = diaryMapper.findDiarySituation(time1, time2, taskId);
        return forThis(diarySituation);
    }

    @Override
    public Diary findByTime(Date date, Long taskId, Long studentId) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date time1 = cal.getTime();
        cal.get(Calendar.DAY_OF_YEAR);
        cal.add(Calendar.DATE, 1);
        Date time2 = cal.getTime();
        Diary diaryMapper1 = diaryMapper.findTodayDiaryByStudentId(studentId, taskId, time1, time2);
        String img = diaryMapper1.getImg();
        //分割字符串
        String[] imgs;
        String meter = ",";
        imgs = img.split(meter);
        diaryMapper1.setImgs(imgs);
        diaryMapper1.setImg(null);
        return diaryMapper1;
    }

    @Override
    public PageInfo<Diary> findDiariesWithLikesAndCommentsByTaskId(Long taskId, Integer limit) {
        Task task = taskService.findById(taskId);
        Long teachlinkId = task.getTeachlinkId();
        Teachlink teachlink = teachlinkService.findById(teachlinkId);
//        PageHelper.startPage(page, size);
        List<Diary> diaries;
        long total;
        if (teachlink.getMode() == 0) {
            diaries = diaryMapper.findDiariesWithLikesAndCommentsByTaskId(taskId, limit);
            total = diaryMapper.countByTaskId(taskId);
        } else {
            diaries = diaryMapper.findDiariesWithLikesAndCommentsByTeachlinkId(teachlinkId, limit);
            total = diaryMapper.countByTeachlinkId(teachlinkId);
        }
        PageInfo<Diary> pageInfo = new PageInfo<>(diaries);
        pageInfo.setTotal(total);
        return pageInfo;
    }

    @Override
    public DiaryDetails findDiaryDetailsByTeachlinkId(Long teachlinkId) throws PtpException {
        Task task = this.taskService.findTaskByTeachlinkId(teachlinkId);
        if (task == null) {
            throw new PtpException(400, "出错了，您选择的教学环节下没有对应的任务");
        }
        List<DiaryDetails.Student> students = this.diaryMapper.findStuDiaryDetails(task.getId());
        List<Date> dateList = this.signInDateService.findDateListByTaskId(task.getId());
        return new DiaryDetails(students, dateList);
    }

    @Override
    public boolean delete(Diary diary) {
        int i = diaryMapper.deleteByDiaryIdAndStudentId(diary.getId(), diary.getStudentId());
        return i > 0;
    }

    @Override
    public boolean like(Like like) {
        like.setStatus(0);
        Date now = new Date();
        like.setCreateTime(now);
        like.setUpdateTime(now);
        Like exist = likeMapper.findByDiaryIdAndStudentId(like.getDiaryId(), like.getStudentId());
        if (exist != null) {
            return false;
        }
        int i = likeMapper.insert(like);
        return i > 0;
    }

    @Override
    public boolean unlike(Like like) {
        int i = likeMapper.deleteByDiaryIdAndStudentId(like.getDiaryId(), like.getStudentId());
        return i > 0;
    }

    @Override
    public boolean postComment(Comment comment) {
        comment.setStatus(0);
        Date now = new Date();
        comment.setCreateTime(now);
        comment.setUpdateTime(now);
        int i = commentMapper.insert(comment);
        return i > 0;
    }

    @Override
    public boolean deleteComment(Long commentId, Long studentId) {
        int i = commentMapper.deleteByCommentIdAndStudentId(commentId, studentId);
        return i > 0;
    }

    @Override
    public List<DiaryVO> findByTaskAndStudent(Long taskId, Long studentId) {
        // TODO: 2019/8/27 是否已经被推优
        return this.diaryMapper.findByTaskAndStudent(taskId, studentId);
    }

    @Override
    public void excellentDiary(Long diaryId) throws PtpException {
        try {
            this.diaryMapper.excellentDiary(diaryId);
        } catch (Exception e) {
            throw new PtpException(500, "推优失败，未知错误");
        }
    }

    @Override
    public PageInfo<Diary> findDiariesWithLikesAndCommentsByTaskIds(Long[] taskIds, Integer page, Integer size) {
        List<Diary> diaries = new ArrayList<>();
        long total = 0L;
        int limit = page * size;
        for (Long taskId : taskIds) {
            PageInfo<Diary> diaryList = findDiariesWithLikesAndCommentsByTaskId(taskId, limit);
            diaries.addAll(diaryList.getList());
            total += diaryList.getTotal();
        }
        diaries.sort((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
        int fromIndex = limit - size;
        int diarySize = diaries.size();
        int toIndex = limit > diarySize ? diarySize : limit;
        if (fromIndex >= diarySize) {
            diaries = new ArrayList<>();
        } else {
            diaries = diaries.subList(fromIndex, toIndex);
        }
        PageInfo<Diary> pageInfo = new PageInfo<>(diaries);
        pageInfo.setPageNum(page);
        pageInfo.setTotal(total);
        return pageInfo;
    }

    @Override
    public List<DiaryCalendarResult> findDiaryCalendar(Long taskId, Long studentId) {
        List<Diary> diaries = findByTaskIdAndStudentId(taskId, studentId);
        List<DiaryCalendarResult> result = new ArrayList<>();
        List<Date> datesNeedSign = signInDateService.findDateListByTaskId(taskId);
        Date today = DateUtils.getTodayDateIgnoreTime();
        Iterator<Diary> iterator = diaries.iterator();
        boolean next = iterator.hasNext();
        Diary diary = next ? iterator.next() : null;
        for (Date date : datesNeedSign) {
            DiaryCalendarResult diaryCalendar = new DiaryCalendarResult();
            result.add(diaryCalendar);
            diaryCalendar.setDate(date);

            if (!date.before(today)) {
                continue;
            }

            if (diary == null) {
                diaryCalendar.setNormal(false);
                continue;
            }

            if (DateUtils.isSameDay(diary.getCreateTime(), date)) {
                diaryCalendar.setDiary(diary);
                diaryCalendar.setNormal(true);
                if (iterator.hasNext()) {
                    diary = iterator.next();
                }
            } else {
                diaryCalendar.setNormal(false);
            }
            if (DateUtils.isToday(date)) {
                diaryCalendar.setNormal(diaryCalendar.getNormal() ? true : null);
            }

        }
        return result;
    }

    private List<Diary> findByTaskIdAndStudentId(Long taskId, Long studentId) {
        return diaryMapper.findByTaskIdAndStudentId(taskId, studentId);
    }

    @Override
    public int getTimesInARow(Long taskId, Long studentId) {
        List<DiaryCalendarResult> diaryCalendar = findDiaryCalendar(taskId, studentId);
        int count = 0;
        for (int i = diaryCalendar.size() - 1; i >= 0; i--) {
            DiaryCalendarResult calendar = diaryCalendar.get(i);
            if (DateUtils.getTodayDateIgnoreTime().after(calendar.getDate())) {
                if (calendar.getNormal()) {
                    break;
                } else {
                    count++;
                }
            }
        }
        return count;
    }

    @Override
    public int getTimesPerWeek(Long taskId, Long studentId) {
        List<Date> dates = DateUtils.getWeekDates();
        List<DiaryCalendarResult> diaryCalendar = findDiaryCalendar(taskId, studentId);
        int count = 0;
        for (DiaryCalendarResult calendar : diaryCalendar) {
            if (dates.contains(calendar.getDate()) && Boolean.FALSE.equals(calendar.getNormal())) {
                count++;
            }
        }
        return count;
    }

    @Override
    public int getTimesInTotal(Long taskId, Long studentId) {
        List<DiaryCalendarResult> diaryCalendar = findDiaryCalendar(taskId, studentId);
        int count = 0;
        for (DiaryCalendarResult calendar : diaryCalendar) {
            if (Boolean.FALSE.equals(calendar.getNormal())) {
                count++;
            }
        }
        return count;
    }

    @Override
    public boolean writeUpDiary(Diary diary) {

        Date startDate =DateUtils.startTime(diary.getCreateTime());
        Date endDate =DateUtils.endTime(diary.getCreateTime());

        boolean ifTodayInSignInDates = signInDateService.ifTodayInSignInDates(diary.getTaskId());
        if (ifTodayInSignInDates) {
            Diary diary1 = diaryMapper.findTodayDiaryByStudentId(diary.getStudentId(),
                    diary.getTaskId(), startDate, endDate);
            if (diary1 == null) {
                diary.setUpdateTime(new Date());
                diary.setStatus(0);
                int i = diaryMapper.insert(diary);
                System.out.println(i);
                return i>0;
            }
        }
        return false;
    }
        @Override
        public boolean alertDiary (AlertBody alert){
            Student student = this.studentService.findById(alert.getStudentId());
            Map<String, TemplateData> data = new HashMap<>();
            String content = "今天还没有写日志,请尽快提交日志！（已提交日志请忽略）";
            Date date = DateUtils.endTime(new Date());
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            String s = df.format(date);
            data.put("keyword1", new TemplateData("日志提交"));
            data.put("keyword2", new TemplateData(content));
            data.put("keyword3", new TemplateData(s));
            data.put("keyword4", new TemplateData("请尽快提交日志!"));
            boolean result = wxService.sendMessage(student.getOpenId(), WxTmplMsg.TYPE_DIARY, data);
            if (result) {
                Message message = new Message();
                message.setStudentId(student.getId());
                message.setTaskId(alert.getTaskId());
                message.setContent(content);
                return messageService.saveDiaryMessage(message);
            }
            return false;
        }
    }
